package EA.testproblems;
import EA.*;

/**
   This testproblem is a simple problem for initial tuning of multimodal 
   optimization algorithms. <br><br>

   <table border="0" cellpadding="2" cellspacing="0">
   <tr bgcolor="#a0a0a0">
   <td colspan="2" valign="top"><b>Problem description</b></td>
   </tr>
   <tr bgcolor="#e0e0e0">
   <td valign="top" width="200"><b>Name:</b></td>
   <td valign="top">Ursem multimodal 1</td>
   </tr>
   <tr bgcolor="#e0e0e0">
   <td valign="top"><b>Nickname:</b></td>
   <td valign="top">&nbsp;</td>
   </tr>
   <tr bgcolor="#e0e0e0">
   <td valign="top"><b>Intended usage:</b></td>
   <td valign="top">Initial finetuning and tests of especially multimodal algorithms.</td>
   </tr>

   <tr>
   <td colspan="2" valign="top">&nbsp;</td>
   </tr>
   <tr bgcolor="#a0a0a0">
   <td colspan="2" valign="top"><b>Problem details</b></td>
   </tr>
   <tr bgcolor="#e0e0e0">
   <td valign="top"><b>Function:</b></td>
   <td valign="top">sin(2x - 0.5pi) + 3cos(y) + 0.5x</td>
   </tr>
   <tr bgcolor="#e0e0e0">
   <td valign="top"><b>Plots:</b></td>
   <td valign="top"><img src="../../images/testproblems/ursemmultimodal1.gif">&nbsp;&nbsp;
   <img src="../../images/testproblems/ursemmultimodal1_contour.gif"></td>
   </tr>
   <tr bgcolor="#e0e0e0">
   <td valign="top"><b>Ranges:</b></td>
   <td valign="top">x = [-2.5:3.0]&nbsp;&nbsp;y = [-2.0:2.0] </td>
   </tr>
   <tr bgcolor="#e0e0e0">
   <td valign="top"><b>Type:</b></td>
   <td valign="top">Maximization</td>
   </tr>
   <tr bgcolor="#e0e0e0">
   <td valign="top"><b>No. of maximas:</b></td>
   <td valign="top">2</td>
   </tr>
   <tr bgcolor="#e0e0e0">
   <td valign="top"><b>No. of minimas:</b></td>
   <td valign="top">6</td>
   </tr>
   <tr bgcolor="#e0e0e0">
   <td valign="top"><b>Optimum radius:</b></td>
   <td valign="top">0.2</td>
   </tr>
   <tr bgcolor="#e0e0e0">
   <td valign="top"><b>Optimum descriptions:</b></td>
   <td valign="top">The two maximas are located along the x-axis. They don't 
   have the same height. The six minimas are located on the edge of the
   searchspace.</td>
   </tr>
   <tr bgcolor="#e0e0e0">
   <td valign="top"><b>Known optimums:</b></td>
   <td valign="top">
   GMAX(1.697136454,0),
   LMAX(-1.444456199,0),
   LMIN(-0.1263401276,2), 
   LMIN(-0.1263401276,-2),
   LMIN(-2.5,2.0),
   LMIN(-2.5,-2.0),
   LMIN(3.0,2.0),
   LMIN(3.0,-2.0)
   <br><font size=1>Capital letters 
   means that the precise optimum is known, lowercase letters is the best known 
   so far.</font></td>
   </tr>
   <tr>
   <td colspan="2" valign="top">&nbsp;</td>
   </tr>
   <tr bgcolor="#a0a0a0">
   <td colspan="2" valign="top"><b>Plotting details</b></td>
   </tr>
   
   <tr bgcolor="#e0e0e0">
   <td valign="top"><b>GNUPlot code:</b></td>
   <td valign="top">
   set hidden3d<br>
   set isosamples 50<br>
   set view 80,15<br>
   splot [-2.5:3] [-2:2] sin(2*x-0.5*pi) + 3*cos(y) +0.5*x</td>
   </tr>
   </table>
*/
public class UrsemMultimodal1 extends NumericalProblem
{
  // Easier way to build max
  private double[][] lmax =  {{1.697136454,0},{-1.444456199,0}};
  private double[][] lmin =  {{-0.1263401276,2}, {-0.1263401276,-2},{-2.5,2.0},
			      {-2.5,-2.0},{3.0,2.0},{3.0,-2.0}};

  public UrsemMultimodal1()
    {
      super();

      double[] optimums;

      name = "Ursem Multimodal 1";
      objectivefunction = new NumericalFitness(){
	public double Fitness_calcFitness_inner(double[] realpos)
	{
	  return Math.sin(2*realpos[0] - 0.5*Math.PI) + 3*Math.cos(realpos[1]) + 0.5*realpos[0];
	};
      };
      dimensions = 2;
      ismaximization = true;
      optimumradius = 0.2;

      intervals = new Interval[2];
      intervals[0] = new Interval(-2.5,3);
      intervals[1] = new Interval(-2,2);

      // Set up known maximas
      knownmaxima = new NumericalOptimum[lmax.length];

      for (int i=0;i<lmax.length;i++) {
	optimums = new double[dimensions];
	optimums[0] = lmax[i][0];
	optimums[1] = lmax[i][1];
	knownmaxima[i] = new NumericalOptimum(optimums, objectivefunction.calcFitness(optimums), true, false, i);
      }

      // Set up known minimas
      knownminima = new NumericalOptimum[lmin.length];

      for (int i=0;i<lmin.length;i++) {
	optimums = new double[dimensions];
	optimums[0] = lmin[i][0];
	optimums[1] = lmin[i][1];
	knownminima[i] = new NumericalOptimum(optimums, objectivefunction.calcFitness(optimums), false, false, i);
      }
    }
}



